Completed
Push — master ( e26402...4d0225 )
by greg
01:48
created

prepare.js ➔ indexEachBlocks   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 1
c 2
b 1
f 0
nc 1
nop 2
dl 0
loc 30
rs 8.8571

1 Function

Rating   Name   Duplication   Size   Complexity  
A prepare.js ➔ ... ➔ ??? 0 23 3
1
import Handlebars from 'handlebars'
2
3
import {
4
  cmsData
5
  ,config
6
  ,cmsTemplates
7
} from '../../'
8
9
/**
10
 * THIS:
11
<span>{{abe type='text' key='text_visible'}}</span>
12
13
 * BECOME:
14
<span data-abe-text_visible="text_visible" >{{abe type='text' key='text_visible'}}</span>
15
16
 * @param {[type]} template [description]
17
 */
18
export function addAbeDataAttrForHtmlTag(template) {
19
  var match
20
  var key
21
  var getattr
22
23
  while (match = cmsData.regex.abePattern.exec(template)) {
24
    key = cmsData.regex.getAttr(match, 'key')
25
26
    if (cmsData.regex.isSingleAbe(match, template)) {
27
      getattr = key.replace(/\./g, '-')
28
    } else {
29
      getattr = key.replace('.', '[index].')
30
    }
31
32
    template = template.replace(
33
      cmsData.regex.escapeTextToRegex(match[0], 'g'),
34
      ' data-abe-' + cmsData.regex.validDataAbe(getattr) + '="'  + getattr + '" ' + match[0]
35
    )
36
  }
37
38
  return template
39
}
40
41
export function addHasAbeAttr(text) {
42
  return text.replace('}}', ' has-abe=1}}')
43
}
44
45
export function getAbeAttributeData(match, text, htmlAttribute, abeTag) {
46
  var valueOfAttritube
47
  var key = cmsData.regex.getAttr(match, 'key')
48
  var res
49
50
  if (cmsData.regex.isSingleAbe(match, text)) {
51
    valueOfAttritube = key.replace(/\./g, '-')
52
    key = cmsData.regex.validDataAbe(valueOfAttritube)
53
    key = key.replace(/\./g, '-')
54
    res = ' data-abe-attr-' + valueOfAttritube + '="'  + htmlAttribute + '"' + ' data-abe-' + valueOfAttritube + '="'  + key + '"' + abeTag
55
  }else {
56
    valueOfAttritube = key.split('.')
57
    var parentKey = valueOfAttritube.shift()
58
    valueOfAttritube = `${parentKey}[index].${valueOfAttritube[0]}`
59
    var valueOfAttritubeIndexed = valueOfAttritube.replace(/\[index\]/, '{{@index}}')
60
    key = cmsData.regex.validDataAbe(valueOfAttritube)
61
62
    res = ` data-abe-attr-${valueOfAttritube}="${htmlAttribute}"  data-abe-${valueOfAttritube}="${key}"`
63
    + ` data-abe-attr-${valueOfAttritubeIndexed}="${htmlAttribute}" data-abe-${valueOfAttritubeIndexed}="${key}"${abeTag}`
64
  }
65
66
  return res
67
}
68
69
/**
70
 *
71
 * IF ABE TAG SINGLE (NOT ABE EACH STATEMENT)
72
 * 
73
 * THIS:
74
<img src="{{abe type='image' key='image_key' tab='default'}}" alt="">
75
76
 * BECOME:
77
<img data-abe-attr-image_key="src" data-abe-image_key="image_key" data-abe-attr-image_key="src"
78
data-abe-image_key="image_key" src="{{abe type='image' key='image_key' tab='default' has-abe=1 has-abe=1}}" alt="">
79
80
 *
81
 * IF ABE EACH TAG
82
 * THIS:
83
{{#each test}}
84
  <img src="{{abe type='image' key='test.img' desc='test_img' tab='default'}}" alt="">
85
{{/each}}
86
87
 * BECOME:
88
{{#each test}}
89
  <img data-abe-attr-test[index].img="src" data-abe-test[index].img="test[index].img" src="{{abe type='image' key='test.img' desc='test_img' tab='default' has-abe=1}}" alt="">
90
{{/each}}
91
92
 * @param {[type]} template [description]
93
 */
94
export function addAbeDataAttrForHtmlAttributes(template) {
95
  var text = template.replace(/<([A-Za-z]+)/g, '\nABE_SPLIT<$1')
96
  let abeTagIntoAttribute = text.match(cmsData.regex.abeAsAttributePattern)
97
98
  if (abeTagIntoAttribute != null) {
99
    Array.prototype.forEach.call(abeTagIntoAttribute, (abeIntoTag) => {
100
      let matchAbeTag = /({{abe.*?[\s\S].*?}})/g.exec(abeIntoTag)
101
102
      if(matchAbeTag != null && matchAbeTag[1] != null) {
103
        var toReplace = cmsTemplates.prepare.getAbeAttributeData(matchAbeTag[1], text, (abeIntoTag.split('=')[0]).trim(), abeIntoTag)
104
105
        toReplace = toReplace.replace(
106
          cmsData.regex.escapeTextToRegex(matchAbeTag[1]),
107
          cmsTemplates.prepare.addHasAbeAttr(matchAbeTag[1])
108
        )
109
110
        text = text.replace(
111
          cmsData.regex.escapeTextToRegex(abeIntoTag),
112
          toReplace
113
        )
114
      }
115
    })
116
  }
117
  text = text.replace(/\nABE_SPLIT</g, '<')
118
119
  return text
120
}
121
122
/**
123
 * Example:
124
 *
125
 *
126
 * THIS:
127
{{abe type='data' key='data_key' source='select title from article' display='title' editable='true' tab='default'}}
128
129
{{#each data_key}}
130
  {{title}}
131
{{/each}}
132
133
 *
134
 * BECOME THIS
135
136
{{abe type='data' key='data_key' source='select title from article' display='title' editable='true' tab='default'}}
137
138
{{#each data_key}}
139
  {{title}}
140
{{/each}}<!-- [[data_key]] %7B%7B%23each%20data_key%7D%7D%0A%09%7B%7Btitle%7D%7D%0A%7B%7B/each%7D%7D -->
141
142
 * @param {[type]} template [description]
143
 * @param {[type]} json     [description]
144
 */
145
export function addAbeSourceComment(template, json) {
146
  
147
  // Don't know what it does...
148
  if(typeof json.abe_source !== 'undefined' && json.abe_source !== null) {
149
    var keys = Object.keys(json.abe_source)
150
    
151
    for(var i in keys) {
0 ignored issues
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
152
      var replaceEach = new RegExp(`<!-- \\[\\[${keys[i]}\\]\\][\\s\\S]*?-->`, 'g')
153
      template = template.replace(replaceEach, '')
154
155
      var patAttrSource = new RegExp(' ([A-Za-z0-9\-\_]+)=["|\'].*?({{' + keys[i] + '}}).*?["|\']', 'g')
156
      var patAttrSourceMatch = template.match(patAttrSource)
157
158
      if(patAttrSourceMatch != null) {
159
        let checkEscapedRegex = /["|'](.*?)["|']/
160
        let patAttrSourceInside = new RegExp('(\\S+)=["\']?((?:.(?!["\']?\\s+(?:\\S+)=|[>"\']))+.)["\']?({{' + keys[i] + '}}).*?["|\']', 'g')
161
        Array.prototype.forEach.call(patAttrSourceMatch, (pat) => {
162
          let patAttrSourceCheck = patAttrSourceInside.exec(pat)
163
          if(patAttrSourceCheck != null) {
164
            
165
            let checkEscaped = checkEscapedRegex.exec(patAttrSourceCheck[0])
166
            if(checkEscaped != null && checkEscaped.length > 0) {
167
              checkEscaped = escape(checkEscaped[1])
168
              template = template.replace(
0 ignored issues
show
Bug introduced by
The variable template is changed as part of the for-each loop for example by template.replace(replaceEach, "") on line 153. Only the value of the last iteration will be visible in this function if it is called after the loop.
Loading history...
169
                patAttrSourceCheck[0],
170
                ` data-abe-attr="${patAttrSourceCheck[1]}" data-abe-attr-escaped="${checkEscaped}" data-abe="${keys[i]}" ${patAttrSourceCheck[0]}`
0 ignored issues
show
introduced by
The variable i is changed by the for-each loop on line 151. Only the value of the last iteration will be visible in this function if it is called outside of the loop.
Loading history...
171
              )
172
            }
173
          }
174
        })
175
      }
176
177
      var eachSource = new RegExp(`({{#each ${keys[i]}}[\\s\\S a-z]*?{{\/each}})`, 'g')
178
      var matches = template.match(eachSource)
179
      if(typeof matches !== 'undefined' && matches !== null) {
180
        Array.prototype.forEach.call(matches, (match) => {
181
          template = template.replace(match, `${match}<!-- [[${keys[i]}]] ${cmsTemplates.encodeAbeTagAsComment(match)} -->`)
0 ignored issues
show
Bug introduced by
The variable template is changed as part of the for-each loop for example by template.replace(replaceEach, "") on line 153. Only the value of the last iteration will be visible in this function if it is called after the loop.
Loading history...
introduced by
The variable i is changed by the for-each loop on line 151. Only the value of the last iteration will be visible in this function if it is called outside of the loop.
Loading history...
182
        })
183
      }
184
    }
185
  }
186
187
  return template
188
}
189
190
/**
191
 * THIS:
192
<span>{{abe type='text' key='text_visible'}}</span>
193
194
 * BECOME:
195
<span><abe>{{abe type='text' key='text_visible'}}</abe></span>
196
197
 * @param {[type]} template [description]
198
 */
199
export function addAbeHtmlTagBetweenAbeTags(template) {
200
  var match
201
  while (match = cmsData.regex.abePattern.exec(template)) {
202
    template = template.replace(cmsData.regex.escapeTextToRegex(match[1], 'g'), '<abe>' + match[1].trim() + '</abe>')
203
  }
204
205
  return template
206
}
207
208
/**
209
 * THIS:
210
[index].
211
212
 * BECOME:
213
{{@index}}-
214
215
 *  @param  {[type]} template [description]
216
 * @return {[type]}          [description]
217
 */
218
export function replaceAbeEachIndex(template) {
219
  return template.replace(/\[index\]\./g, '{{@index}}-')
220
}
221
222
export function removeHiddenAbeTag(template) {
223
  return template.replace(/(\{\{abe.*visible=[\'|\"]false.*\}\})/g, '')
224
}
225
226
/**
227
 * Remove {{abe type=*}} from html if attribute visible="false"
228
 * @param  {[type]} template [description]
229
 * @return {[type]}          [description]
230
 */
231
export function removeHandlebarsRawFromHtml(template) {
232
  return template.replace(/\{\{\{\{\/?raw\}\}\}\}/g, '')
233
}
234
235
/**
236
 * split {{#each}}...{{/each}} into an array
237
 * 
238
 * @param  {[type]} template [description]
239
 * @return {[type]}          [description]
240
 */
241
export function splitEachBlocks(template) {
242
  var block
243
  var blocks = []
244
245
  while (block = cmsData.regex.blockPattern.exec(template)) {
246
    blocks.push(block[1])
247
  }
248
249
  return blocks
250
}
251
252
export function indexEachBlocks(template, onlyHtml) {
253
  // create an array of {{each}} blocks
254
  var blocks = cmsTemplates.prepare.splitEachBlocks(template)
255
256
  Array.prototype.forEach.call(blocks, (block) => {
257
    var key = block.match(/#each (.*)\}\}/)[1]
258
    var match
259
260
    if(!onlyHtml) {
261
262
      var voidData = {}
263
      voidData[key] = [{}]
264
      var blockCompiled = Handlebars.compile(block.replace(/{{abe (.*?)}}/g, '[[abe $1]]').replace(new RegExp(`\\.\\.\/${config.meta.name}`, 'g'), config.meta.name))
265
      var blockHtml = blockCompiled(voidData, {data: {intl: config.intlData}}).replace(/\[\[abe (.*?)\]\]/g, '{{abe $1}}')
266
267
      // je rajoute un data-abe-block avec index sur tous les tags html du bloc each
268
      var textEachWithIndex = block.replace(/(<(?![\/])[A-Za-z0-9!-]*)/g, '$1 data-abe-block="' + key + '{{@index}}"')
269
270
      // je remplace le block dans le texte par ça
271
      template = template.replace(block, textEachWithIndex + `<!-- [[${key}]] ${cmsTemplates.encodeAbeTagAsComment(blockHtml)} -->`)
272
    }
273
274
    // Pour chaque tag Abe
275
    while (match = cmsData.regex.abeTag.exec(block)) {
276
      template = cmsTemplates.prepare.addAbeDictionnary(template, match[0], key)
0 ignored issues
show
Bug introduced by
The variable template is changed as part of the while loop for example by cmsTemplates.prepare.add...template, match.0, key) on line 276. Only the value of the last iteration will be visible in this function if it is called after the loop.
Loading history...
277
    } 
278
  })
279
280
  return template
281
}
282
283
/**
284
 * split {{#each}}...{{/each}} into an array
285
 *
286
 * THIS:
287
  {{abe type='text' key='test.title' desc='test title' tab='default'}}
288
289
 * BECOME THIS:
290
  {{abe dictionnary='test' type='text' key='test.title' desc='test title' tab='default'}}
291
292
 * 
293
 * @param  {[type]} template [description]
294
 * @return {[type]}          [description]
295
 */
296
export function addAbeDictionnary(template, match, key) {
297
  if(cmsData.regex.isEachStatement(match)) return
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
298
299
  if(cmsData.regex.isBlockAbe(match)){
300
    var abeDictionnary = match.replace(new RegExp('(key=[\'|"])' + key + '.', 'g'), '$1' + key + '[index].')
301
                               .replace(/\{\{abe/, '{{abe dictionnary=\'' + key + '\'')
302
303
    template = template.replace(match, abeDictionnary)
304
  }
305
306
  return template
307
}
308